-
Notifications
You must be signed in to change notification settings - Fork 693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expander Fixes #4394
Expander Fixes #4394
Conversation
The header and content container elements should always be stretched to give child controls maximum available area.
I think there are more issues with the default Expander style. This should be reviewed more carefully, I only fixed the ones I noticed. I'm certain all the height/width settings are not optimal. The control needs to be much more responsive in its architecture and I only did a quick pass on fixing this. (Stretching vertically is still likely not supported for example) |
This aligns with the default Button style
This aligns with the default Button style
These should follow the layout root (parent grid) sizing.
dev/Expander/Expander.xaml
Outdated
HorizontalAlignment="Stretch" | ||
HorizontalContentAlignment="Stretch" | ||
VerticalContentAlignment="Center" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why these shouldn't still be template bound and then given these values as defaults in the Style setters like the other properties? Otherwise it's even harder to customize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that we have to worry about positioning two 'areas' of the control separately: The Header and the Content. There are cases where you want the Header left aligned for example, but the actual content of the expander stretched.
What is done now is the Horizontal/VerticalContentAlignment is template bound to the content presenter. If we template bound in both areas we are forcing the header/content to always be in sync. Instead, stretching the 'container' elements allows independent positing of child content elements in either the header or the content area while also still supporting horizontal stretch.
Adding lightweight styling resources separate for the header/content area is also possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, we should template bind the most common one that developers would want to customize and expose the other as theme resources so they can be customized as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Experience tells me all properties of the Expander needs to be template bound to the content area rather than the header area. It will be most intuitive that way but it's opposite of how the code currently functions so additional changes are needed. (Background/Padding, etc. map to the header) We can expose theme resources for these header properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: I should add that WPF appears to map some properties to both the header and the content areas simultaneously. I'm not sure I agree with that approach and think we should keep them separate. This is just FYI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree they should be seperate and generally we expect these properties to apply to the content area. So the control's background property should set the background of the content we provide to the control in its (metadata marked) content property.
In reply to: 590643542 [](ancestors = 590643542)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that makes sense. But the other ones should at least be controlled by static/theme resources to provide better customization. Expander is odd because we usually see folks wanting to customize the header itself compared to the content, as the content is pretty much all end-developer driven vs. any chrome provided by the control itself at least in the default templates we've used in the past.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the other ones should at least be controlled by static/theme resources to provide better customization
Yes, I'll add the lightweight styling resources so these can be customized without re-templating. There is well established convention for this now (but we are creating a lot of named resources indicating the styling system is deficient...)
Expander is odd because we usually see folks wanting to customize the header itself compared to the content,
I can see that point. Also keep in mind that the header is also one of the places the developer should customize the least. The design of the header is really set by the fluent design system and shouldn't change much so that end-users recognize it. It's like a ComboBox in my mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added two resources to control the header's content alignment: ExpanderHeaderHorizontalContentAlignment
and ExpanderHeaderVerticalContentAlignment
. I am leaving the HorizontalAlignment of the header itself to stretched. This ensures it fits the grid which is the root for sizing purposes. Child content can still be aligned any way you would like (not only stretched).
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
This reverts commit 1223fb1.
This reverts commit 363c732.
- Header and content resources are clearly named and separated - Relevant control properties now apply to the content area instead of header
- Border thickness of the content area is no longer controlled by the BorderThickness DP of the control itself - This is required as BorderThickness of the control has local precedence over the visual state setter. - The correct solution for this is another filter converter for border thickness
BorderBrush="{ThemeResource ExpanderDropDownBorderBrush}" | ||
BorderThickness="{StaticResource ExpanderDropdownDownBorderThickness}" | ||
BorderBrush="{TemplateBinding BorderBrush}" | ||
BorderThickness="{StaticResource ExpanderContentDownBorderThickness}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not ideal.
BorderThickness="{StaticResource ExpanderContentDownBorderThickness}"
should beBorderThickness="{TemplateBinding BorderThickness}"
However, that would not work due to the BorderThickness
of the control having local precedence (higher precedence than the visual state setter). The visual state is being used to switch between border thicknesses that have the top or bottom edge set to zero depending on the expand direction.
The correct solution to this is to add another filter converter for the border thickness similar to the CornerRadius. I expect push back so I didn't implement that.
What is done now is considered a hack but is usable for an initial release. Developers can still customize the thickness of the content area using ExpanderContentDownBorderThickness
and ExpanderContentUpBorderThickness
even while the BorderThickness
of the control is ignored.
This is ready for review and merge. |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderBorderBrush}" /> | ||
<Setter Property="Padding" Value="{StaticResource ExpanderHeaderPadding}" /> | ||
<Setter Property="HorizontalAlignment" Value="Stretch" /> | ||
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this HorizontalContentAlignment no longer needed? Looking at this change it looks like the template never actually used this before. Is this just deleting unused lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The default actually should be center per Expander Fixes #4394 (comment)
- I followed convention of the Button template
- When the default value of 'Center' is required, the property is simply omitted. This is better as all controls will fallback to the same default so if once in 1000 years the default was actually changed you wouldn't need to go and update all the templates (single source of truth). The rule of thumb: only change what you need to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tashatitova Did I misunderstand about the HorizontalContentAlignment? Were you only referring to VerticalContentAlignment in that comment referenced above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tashatitova Can you confirm about HorizontalContentAlignment? The more I think about it, I think this was my misunderstanding and you were only talking about VerticalContentAlignment. I would like to make this change and get this PR merged ASAP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just re-read it and your last comment emphasizes vertical. I'm going to make the change and add back HorizontalContentAlignment. Horizontal seems like it should be Left so @StephenLPeters was right to point this out.
|
||
<!-- Content --> | ||
<StaticResource x:Key="ExpanderContentBackground" ResourceKey="CardBackgroundFillColorSecondaryBrush" /> | ||
<StaticResource x:Key="ExpanderContentBorderBrush" ResourceKey="ExpanderHeaderBorderBrush" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested that this works? I'm worried that if you override the ExpanderHeaderBorderBrush at the local scope the ExpanderContentBorderBrush wont see your override. This is because the resource lookup doesn't restart when a resource redirection is encountered. So when the template is expanded and this resource is found, we'll start looking for a value for the ExpanderHeaderBorderBrush from our current position in the tree walk, which will miss the local overrides lower in the tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested that this works
No, I have not tested this specifically and didn't have a reason to at the time. My changes here were only renaming and I copied the original functionality. Code before renaming is below:
<StaticResource x:Key="ExpanderBorderBrush" ResourceKey="CardStrokeColorDefaultBrush" /> |
microsoft-ui-xaml/dev/Expander/Expander_themeresources.xaml
Lines 45 to 46 in d20fcb8
<StaticResource x:Key="ExpanderDropDownBackground" ResourceKey="CardBackgroundFillColorSecondaryBrush" /> | |
<StaticResource x:Key="ExpanderDropDownBorderBrush" ResourceKey="ExpanderBorderBrush" /> |
ExpanderBorderBrush
renamed to ExpanderHeaderBorderBrush
ExpanderDropDownBorderBrush
renamed to ExpanderContentBorderBrush
Resource resolution is tricky to understand for those outside the codebase and is not well documented at least that I've found. So I'll take your word for how it functions in this area. If you want me to make the change that's fine. It will just be set to CardStrokeColorDefaultBrush
as well.
Edit:
I'm worried that if you override the ExpanderHeaderBorderBrush at the local scope the ExpanderContentBorderBrush wont see your override
Actually, that's probably not a bad thing. If you change the Header resource one wouldn't expect the Content to change with it. Either way this line of code should be modified as indicated above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note ExpanderHeaderDisabledBorderBrush
is also affected but would make sense to follow the ExpanderHeaderBorderBrush
when changed. Still, this should change as well due to potential resource lookup issues.
<StaticResource x:Key="ExpanderHeaderDisabledBorderBrush" ResourceKey="ExpanderHeaderBorderBrush" /> |
There is concern these would not be re-evaluated when expected
@StephenLPeters I see some commits that are going to cause a lot of merge issues. What/when is the plan for getting this merged? |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
Description
Closes #4390
Closes #4391
Closes #4248 (The Header is now stretched by default and will respect min/max/width)
Motivation and Context
How Has This Been Tested?
Manually tested in MUXControlsTestApp
Screenshots (if appropriate):